/**
在TypeScript中，映射类型的修饰符用于对原有类型的属性进行修改。通过使用不同的修饰符，可以生成新的类型，满足不同的需求。
  1. 可选属性修饰符  `?` 
  - 使用可选属性修饰符可以将原有类型的所有属性变为可选属性。

    例如：
  type Person = {
        name: string;
        age: number;
    };

    type PartialPerson = {
        [K in keyof Person]?: Person[K];
    };

    // PartialPerson 的类型为 { name?: string; age?: number; }
  2. 只读属性修饰符  `readonly` 
  - 使用只读属性修饰符可以将原有类型的所有属性变为只读属性，确保这些属性在对象创建后不能被修改。

    例如：
  type ReadonlyPerson = {
        readonly [K in keyof Person]: Person[K];
    };

    // ReadonlyPerson 的类型为 { readonly name: string; readonly age: number; }
  3. 组合修饰符
  - 可以将可选属性和只读属性修饰符结合使用，以创建既可选又只读的属性。

    例如：
  type OptionalReadonlyPerson = {
        readonly [K in keyof Person]?: Person[K];
    };

    // OptionalReadonlyPerson 的类型为 { readonly name?: string; readonly age?: number; }
  4. 条件类型结合映射类型
  - 在映射类型中使用条件类型，可以根据属性的类型进行不同的转换。

    例如：
  type Nullable<T> = {
        [K in keyof T]: T[K] extends object ? T[K] | null : T[K];
    };

    type NullablePerson = Nullable<Person>;

    // NullablePerson 的类型为 { name: string | null; age: number | null; }
  5. 总结
  映射类型的修饰符在TypeScript中提供了一种灵活的方式来修改类型的属性。通过使用可选属性、只读属性和条件类型等修饰符，开发者可以根据需求生成新的类型。这种特性在构建复杂数据结构和增强类型安全性方面非常有用，提高了代码的可维护性和可读性。映射类型的修饰符是TypeScript类型系统的重要组成部分。
 */
type MapPerson<Type> = {
  readonly [Property in keyof Type]?: Type[Property]
}

interface IPerson {
  name: string;
  age: number;
  height: number;
  address: string;
}

type IReadonlyPerson = MapPerson<IPerson>

const person: IReadonlyPerson = {
  name: 'map-name',
  age: 18,
  height: 1.88,
  address: '北京市'
}

export {}
